/*
 *    Copyright © OpenAtom Foundation.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

package com.inspur.edp.bef.bizentity.operation;

import com.inspur.edp.bef.bizentity.beenum.BEDeterminationType;
import com.inspur.edp.bef.bizentity.beenum.BEOperationType;
import com.inspur.edp.bef.bizentity.beenum.BETriggerTimePointType;
import com.inspur.edp.bef.bizentity.beenum.RequestNodeTriggerType;
import com.inspur.edp.bef.bizentity.collection.DtmElementCollection;
import com.inspur.edp.bef.bizentity.operation.componentbase.BizParameterCollection;
import java.util.EnumSet;

/**
 * 联动规则元数据定义
 * <p>
 * 描述了一种根据实体属性改变触发的计算逻辑，包含触发计算的时机，触发来源结点以及触发计算时需要执行的构件
 */
public class Determination extends BizOperation implements Cloneable {

  // region 字段
  private BizParameterCollection parameterCollection;
  private DtmElementCollection rqtElements;
  private java.util.HashMap<String, DtmElementCollection> requestChildElements;
  // endregion

  // region 构造函数

  /**
   * 默认构造函数
   */
  public Determination() {

  }

  // endregion

  // region 属性

  /**
   * 操作类型
   */
  @Override
  public BEOperationType getOpType() {
    return BEOperationType.Determination;
  }

  public BizParameterCollection getParameterCollection() {
    return parameterCollection;
  }

  public void setParameterCollection(BizParameterCollection parameterCollection) {
    this.parameterCollection = parameterCollection;
  }

  /**
   * Determination类型
   */
  private BEDeterminationType privateDeterminationType = BEDeterminationType.forValue(0);

  public final BEDeterminationType getDeterminationType() {
    return privateDeterminationType;
  }

  public final void setDeterminationType(BEDeterminationType value) {
    privateDeterminationType = value;
  }

  /**
   * 是否阻止联动计算循环触发
   */
  private boolean runOnce;

  public boolean getRunOnce() {
    return runOnce;
  }

  public void setRunOnce(boolean runOnce) {
    this.runOnce = runOnce;
  }

  /**
   * 触发时机的类型
   */
  private EnumSet<BETriggerTimePointType> privateTriggerTimePointType = EnumSet
      .of(BETriggerTimePointType.forValue(0));

  public final EnumSet<BETriggerTimePointType> getTriggerTimePointType() {
    return privateTriggerTimePointType;
  }

  public final void setTriggerTimePointType(EnumSet<BETriggerTimePointType> value) {
    privateTriggerTimePointType = value;
  }

  /**
   * Node状态触发时机的类型
   */
  private EnumSet<RequestNodeTriggerType> privateRequestNodeTriggerType = EnumSet
      .of(RequestNodeTriggerType.forValue(0));

  public final EnumSet<RequestNodeTriggerType> getRequestNodeTriggerType() {
    return privateRequestNodeTriggerType;
  }

  public final void setRequestNodeTriggerType(EnumSet<RequestNodeTriggerType> value) {
    privateRequestNodeTriggerType = value;
  }

  /**
   * 触发时变更集中需要包含的字段LabelID集合
   */
  public final void setRequestElements(DtmElementCollection value) {
    rqtElements = value;
  }

  public final DtmElementCollection getRequestElements() {
    if (rqtElements == null) {
      rqtElements = new DtmElementCollection();
    }
    return rqtElements;
  }

  public final void setRequestChildElements(java.util.HashMap<String, DtmElementCollection> value) {
    requestChildElements = value;
  }

  public final java.util.HashMap<String, DtmElementCollection> getRequestChildElements() {
    if (requestChildElements == null) {
      requestChildElements = new java.util.HashMap<String, DtmElementCollection>();
    }
    return requestChildElements;
  }
  // endregion

  // region 方法

  /**
   * 判断是否相等
   *
   * @param obj 与当前联动规则比较的对象
   * @return 相等返回true
   */
  @Override
  public boolean equals(Object obj) {
    Determination other = (Determination) ((obj instanceof Determination) ? obj : null);
    return other != null && ((this == other) || equals(other));
  }

  /**
   * 重写Equals
   *
   * @param other
   * @return
   */
  protected final boolean equals(Determination other) {
    return super.equals(other) && getDeterminationType() == other.getDeterminationType()
        && getTriggerTimePointType() == other.getTriggerTimePointType()
        && other.getRequestNodeTriggerType() == getRequestNodeTriggerType();

  }

  /**
   * 重写 GetHashCode
   *
   * @return
   */
  @Override
  public int hashCode() {
    {
      int hashCode = (super.hashCode() * 397);
      hashCode = (hashCode * 397) ^ getDeterminationType().hashCode();
      hashCode = (hashCode * 397) ^ getTriggerTimePointType().hashCode();
      hashCode = (hashCode * 397) ^ getRequestNodeTriggerType().hashCode();
      return hashCode;
    }
  }

  /**
   * Clone方法
   *
   * @param isGenerateId
   * @return
   */
  @Override
  public Determination clone(boolean isGenerateId) {
    Object tempVar = super.clone(isGenerateId);
    Determination result = (Determination) ((tempVar instanceof Determination) ? tempVar : null);
    return result;
  }

  public final void mergeWithDependentDetermination(Determination dependentDetermination) {
    if (getIsRef() || dependentDetermination == null) {
      return;
    }
    mergeOperationBaseInfo(dependentDetermination);
    mergeDeterminationInfo(dependentDetermination);
  }

  private void mergeDeterminationInfo(Determination dependentDetermination) {
    setDeterminationType(dependentDetermination.getDeterminationType());
    setTriggerTimePointType(dependentDetermination.getTriggerTimePointType());
    setRequestNodeTriggerType(dependentDetermination.getRequestNodeTriggerType());

    for (String requestElement : dependentDetermination.getRequestElements()) {
      getRequestElements().add(requestElement);
    }
  }

  // endregion

}
